import 'dart:async';
import 'dart:io';

import 'package:audio_waveforms/audio_waveforms.dart';
import 'package:common/common.dart';
import 'package:path_provider/path_provider.dart';

enum AudioCardState {
  initial,
  recording,
  recordingCompleted,
  playing,
  playingCompleted,
}

/// 录制中  回调录音时间 （秒）
typedef RecorderOnCurrentDuration = void Function(int duration);

/// 开始录制
typedef RecorderOnChangeState = void Function(AudioCardState state, int duration, String fildPath);

class RecorderManager {
  RecorderManager._();

  static final RecorderManager instance = RecorderManager._();

  RecorderController? recorderController;

  late StreamSubscription audioSubscription;

  RecorderOnCurrentDuration? onCurrentDuration;
  RecorderOnChangeState? onChangeState;

  AudioCardState audioCardState = AudioCardState.initial; // 录音状态
  int duration = 0;
  int maxlone = 120;
  int minlong = 6;

  void configRecordParams({int maxTime = 120, int minTime = 6}) {
    // 最长录制时间
    maxlone = maxTime;
    // 最短录制时间
    minlong = minTime;
  }

  RecorderController init() {
    if (recorderController != null) {
      dispose();
    }
    recorderController = RecorderController()
      ..androidEncoder = AndroidEncoder.he_aac
      ..androidOutputFormat = AndroidOutputFormat.mpeg4
      ..iosEncoder = IosEncoder.kAudioFormatMPEG4AAC
      ..sampleRate = 44100;
    // 监听录制时间
    audioSubscription = recorderController!.onCurrentDuration.listen((Duration event) {
      duration = event.inSeconds;
      onCurrentDuration?.call(duration);
      logs('audio = duration =  $duration');
      // 如果超过最大允许录制时间,结束录制
      if (maxlone != 0) {
        if (duration >= maxlone) {
          startOrStopRecording();
        }
      }
    });
    return recorderController!;
    // // 监听结束录制
    // audioSubscription = recorderController.onRecorderStateChanged.listen((RecorderState state) {
    //   logs('audio = onDone');
    //   // onEnd?.call(duration, recorderController.lastFilePath);
    //   audioCardState = AudioCardState.initial;
    //   // 重置录制时间
    //   duration = 0;
    // });

    // audioSubscription = recorderController.onRecordingEnded.listen((Duration duration) {
    //   logs('audio = onRecordingEnded');
    //   onEnd?.call(duration.inSeconds, '', AudioCardState.recordingCompleted);
    //   audioCardState = AudioCardState.initial;
    //   // 重置录制时间
    //   duration = 0;
    // });
  }

  /// 开始录制或者停止录制
  void startOrStopRecording() async {
    try {
      if (audioCardState == AudioCardState.recording) {
        if (duration < minlong) {
          // await recorderController?.stop(false);
          // audioCardState = AudioCardState.initial;
          Toast.showText('最少录制${minlong}s');
          return;
        }
        recorderController?.reset();
        String? audioPath = await recorderController?.stop(false);
        if (audioPath != null) {
          audioCardState = AudioCardState.recordingCompleted;
          logs("文件路径 =  $audioPath  文件大小: ${File(audioPath).lengthSync()}");
          onChangeState?.call(AudioCardState.recordingCompleted, duration, audioPath);
        }
      } else {
        String filePath = await getAudiopath();
        await recorderController?.record(path: filePath); // Path is optional
        audioCardState = AudioCardState.recording;
        onChangeState?.call(AudioCardState.recording, 0, filePath);
      }
    } catch (e) {
      logs(e.toString());
    } finally {
      logs('audioCardState == $audioCardState');

      // setState(() {});
      // if (recorderController.hasPermission) {
      //   setState(() {
      //     audioCardState = AudioCardState.recording;
      //   });
      // }
    }
  }

  /// 获取文件路径
  Future<String> getAudiopath() async {
    Directory appDirectory = await getApplicationDocumentsDirectory();
    String audioPath = "${appDirectory.path}/recording.m4a";
    return audioPath;
  }

  /// 删除文件
  void deleteAudioFile({required String audioPath, Function? successCallback}) {
    if (audioPath.isNotEmpty) {
      File file = File(audioPath);
      if (file.existsSync()) {
        file.deleteSync();
        successCallback?.call();
      }
    }
  }

  void dispose() {
    recorderController?.dispose();
    audioSubscription.cancel();
  }
}
